home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / nevow / i18n.py < prev    next >
Text File  |  2006-04-14  |  6KB  |  220 lines

  1. from zope.interface import implements
  2.  
  3. from nevow import inevow
  4.  
  5.  
  6. def languagesFactory(ctx):
  7.     header = inevow.IRequest(ctx).getHeader('accept-language')
  8.     if header is None:
  9.         return []
  10.     langs = []
  11.     for lang in header.split(','):
  12.         quality = 1.0
  13.         if ';' in lang:
  14.             lang, quality = lang.split(';', 1)
  15.             if quality[:2] == 'q=':
  16.                 try:
  17.                     quality = float(quality[2:])
  18.                 except ValueError:
  19.                     pass
  20.         langs.append((quality, lang))
  21.         if '-' in lang:
  22.             langs.append((quality, lang.split('-')[0])) 
  23.     langs.sort(lambda a,b: cmp(b[0], a[0]))
  24.     return [lang for quality, lang in langs]
  25.  
  26.     
  27. class I18NConfig(object):
  28.     implements(inevow.II18NConfig)
  29.  
  30.     def __init__(self,
  31.                  domain=None,
  32.                  localeDir=None,
  33.                  ):
  34.         self.domain = domain
  35.         self.localeDir = localeDir
  36.         
  37. class PlaceHolder(object):
  38.     def __init__(self, translator, *args, **kwargs):
  39.         self.translator = translator
  40.         self.args = args
  41.         self.kwargs = kwargs
  42.         _mod = kwargs.pop('_mod', None)
  43.         if _mod is None:
  44.             _mod = []
  45.         self.mod = _mod
  46.  
  47.     def __mod__(self, other):
  48.         kw = {}
  49.         kw.update(self.kwargs)
  50.         kw['_mod'] = self.mod+[other]
  51.         return self.__class__(self.translator,
  52.                               *self.args,
  53.                               **kw)
  54.  
  55.     def __repr__(self):
  56.         args = []
  57.         if self.args:
  58.             args.append('*%r' % (self.args,))
  59.         args.append('translator=%r' % self.translator)
  60.         if self.kwargs:
  61.             args.append('**%r' % self.kwargs)
  62.         s = '%s(%s)' % (
  63.             self.__class__.__name__,
  64.             ', '.join(args),
  65.             )
  66.         for mod in self.mod:
  67.             s += ' %% %r' % (mod,)
  68.         return s
  69.  
  70. def flattenL10n(placeHolder, ctx):
  71.     kw = placeHolder.kwargs
  72.  
  73.     try:
  74.         languages = inevow.ILanguages(ctx)
  75.     except TypeError:
  76.         pass
  77.     else:
  78.         kw = dict(kw) # copy before we mutate it
  79.         kw['languages'] = languages
  80.  
  81.     try:
  82.         cfg = inevow.II18NConfig(ctx)
  83.     except TypeError:
  84.         pass
  85.     else:
  86.         kw = dict(kw) # copy before we mutate it
  87.         if cfg.domain is not None:
  88.             kw['domain'] = cfg.domain
  89.         if cfg.localeDir is not None:
  90.             kw['localeDir'] = cfg.localeDir
  91.  
  92.     s = placeHolder.translator(*placeHolder.args, **kw)
  93.     for mod in placeHolder.mod:
  94.         s = s % mod
  95.     return s
  96.  
  97.     
  98. class Translator(object):
  99.     """
  100.     A gettext-like Translator for Nevow.
  101.  
  102.     The major difference between this and naive gettext is that with
  103.     Translator, the actual translation is done as part of Nevow's
  104.     flattening process, allowing per-user settings to be retrieved via
  105.     the context.
  106.  
  107.     @ivar translator: the actual translation function to use.
  108.  
  109.     @ivar args: positional arguments to pass to translator.
  110.  
  111.     @ivar kwargs: keyword arguments to pass to translator.
  112.  
  113.     @ivar gettextFunction: If using the default translator function,
  114.     name of GNU gettext function to wrap. Useful for 'ungettext'.
  115.     """
  116.     translator = None
  117.     args = None
  118.     kwargs = None
  119.  
  120.     gettextFunction = 'ugettext'
  121.  
  122.     def _gettextTranslation(self, *args, **kwargs):
  123.         domain = kwargs.pop('domain', None)
  124.         localeDir = kwargs.pop('localeDir', None)
  125.         languages = kwargs.pop('languages', None)
  126.         import gettext
  127.         translation = gettext.translation(
  128.             domain=domain,
  129.             localedir=localeDir,
  130.             languages=languages,
  131.             fallback=True,
  132.             )
  133.         fn = getattr(translation,
  134.                      self.gettextFunction)
  135.         return fn(*args, **kwargs)
  136.  
  137.     def __init__(self, **kwargs):
  138.         """
  139.         Initialize.
  140.  
  141.         @keyword translator: the translator function to use.
  142.  
  143.         @keyword gettextFunction: The GNU gettext function to
  144.         wrap. See class docstring.
  145.  
  146.         @param kwargs: keyword arguments for the translator function.
  147.         """
  148.         translator = kwargs.pop('translator', None)
  149.         if translator is not None:
  150.             self.translator = translator
  151.         if self.translator is None:
  152.             self.translator = self._gettextTranslation
  153.  
  154.         gettextFunction = kwargs.pop('gettextFunction', None)
  155.         if gettextFunction is not None:
  156.             self.gettextFunction = gettextFunction
  157.  
  158.         self.kwargs = kwargs
  159.  
  160.     def __call__(self, *args, **kwargs):
  161.         """
  162.         Translate a string.
  163.  
  164.         @param args: arguments to pass to translator, usually the
  165.         string to translate, or for things like ungettext two strings
  166.         and a number.
  167.  
  168.         @param kwargs: keyword arguments for the translator.
  169.         Arguments given here will override the ones given at
  170.         initialization.
  171.  
  172.         @return: a placeholder that will be translated
  173.         when flattened.
  174.  
  175.         @rtype: PlaceHolder
  176.         """
  177.         kw = dict(self.kwargs)
  178.         kw.update(kwargs)
  179.         return PlaceHolder(self.translator, *args, **kw)
  180.  
  181.         
  182. _ = Translator()
  183.  
  184. ungettext = Translator(gettextFunction='ungettext')
  185.  
  186. def render(translator=None):
  187.     """
  188.     Render a localised message.
  189.  
  190.     >>> from nevow import i18n, rend
  191.     >>> class MyPage(rend.Page):
  192.     ...     render_i18n = i18n.render()
  193.  
  194.     or, to use a specific domain:
  195.  
  196.     >>> from nevow import i18n, rend
  197.     >>> _ = i18n.Translator(domain='foo')
  198.     >>> class MyPage(rend.Page):
  199.     ...     render_i18n = i18n.render(translator=_)
  200.  
  201.     """
  202.     if translator is None:
  203.         translator = _
  204.  
  205.     def _render(page, ctx, data):
  206.         # TODO why does this get page? Is it
  207.         # the Page's self? Why would this look
  208.         # like a bound method?
  209.         children = ctx.tag.children
  210.         ctx.tag.clear()
  211.         for child in children:
  212.             if isinstance(child, basestring):
  213.                 child = translator(child)
  214.             ctx.tag[child]
  215.         return ctx.tag
  216.  
  217.     return _render
  218.  
  219. # TODO also provide macro()
  220.